From dc215839408c983e54ce4c608d06420954f5bbcb Mon Sep 17 00:00:00 2001 From: robertl Date: Mon, 23 Sep 2002 19:51:17 +0000 Subject: [PATCH] Changes in the various binary file formats to improve portability on alternate-endianness file formats (i.e. palm stuff on pc or pc formats on Sparc or Power.) --- gpsbabel/cetus.c | 12 ++--- gpsbabel/defs.h | 14 ++++-- gpsbabel/gpspilot.c | 6 +-- gpsbabel/holux.c | 27 ++++++----- gpsbabel/magnav.c | 24 +++++----- gpsbabel/psp.c | 109 +++++++++++++++++++++++++++++++++++++++----- gpsbabel/util.c | 40 ++++++++++++++-- 7 files changed, 177 insertions(+), 55 deletions(-) diff --git a/gpsbabel/cetus.c b/gpsbabel/cetus.c index c834ab67b..06ebac9c7 100644 --- a/gpsbabel/cetus.c +++ b/gpsbabel/cetus.c @@ -113,10 +113,10 @@ data_read(void) rec = (struct record *) pdb_rec->data; wpt_tmp->shortname = xstrdup(rec->ID); wpt_tmp->description = xstrdup(rec->name); - wpt_tmp->position.altitude.altitude_meters = pdb_read4(&rec->elevation) / 100.0; + wpt_tmp->position.altitude.altitude_meters = be_read32(&rec->elevation) / 100.0; - wpt_tmp->position.longitude.degrees = pdb_read4(&rec->longitude) / 10000000.0; - wpt_tmp->position.latitude.degrees = pdb_read4(&rec->latitude) / 10000000.0; + wpt_tmp->position.longitude.degrees = be_read32(&rec->longitude) / 10000000.0; + wpt_tmp->position.latitude.degrees = be_read32(&rec->latitude) / 10000000.0; if (rec->year != 0xff) { struct tm tm = {0}; @@ -167,9 +167,9 @@ cetus_writewpt(waypoint *wpt) rec->year = 0xff; } - pdb_write4(&rec->longitude, wpt->position.longitude.degrees * 10000000.0); - pdb_write4(&rec->latitude, wpt->position.latitude.degrees * 10000000.0); - pdb_write4(&rec->elevation, wpt->position.altitude.altitude_meters * 100.0); + be_write32(&rec->longitude, wpt->position.longitude.degrees * 10000000.0); + be_write32(&rec->latitude, wpt->position.latitude.degrees * 10000000.0); + be_write32(&rec->elevation, wpt->position.altitude.altitude_meters * 100.0); opdb_rec = new_Record (0, 0, ct++, sizeof(*rec), (const ubyte *)rec); diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index 71341364b..c7b248279 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -131,10 +131,14 @@ typedef struct { } pdb_16; /* - * Protypes for Palm/OS helpers. + * Protypes for Endianness helpers. */ -signed int pdb_read2(pdb_16 *p); -signed int pdb_read4(pdb_32 *p); -void pdb_write2(pdb_16 *pp, unsigned i); -void pdb_write4(pdb_32 *pp, unsigned i); +signed int be_read16(void *p); +signed int be_read32(void *p); +signed int le_read16(void *p); +signed int le_read32(void *p); +void be_write16(void *pp, unsigned i); +void be_write32(void *pp, unsigned i); +void le_write16(void *pp, unsigned i); +void le_write32(void *pp, unsigned i); diff --git a/gpsbabel/gpspilot.c b/gpsbabel/gpspilot.c index 22e154165..bf1b669c2 100644 --- a/gpsbabel/gpspilot.c +++ b/gpsbabel/gpspilot.c @@ -93,9 +93,9 @@ data_read(void) wpt_tmp = xcalloc(sizeof(*wpt_tmp),1); rec = (struct record *) pdb_rec->data; - wpt_tmp->position.longitude.degrees = pdb_read4(&rec->longitude) / 3.6e6; - wpt_tmp->position.latitude.degrees = pdb_read4(&rec->latitude) / 3.6e6; - wpt_tmp->position.altitude.altitude_meters = pdb_read2(&rec->elevation) / 100.0; + wpt_tmp->position.longitude.degrees = be_read32(&rec->longitude) / 3.6e6; + wpt_tmp->position.latitude.degrees = be_read32(&rec->latitude) / 3.6e6; + wpt_tmp->position.altitude.altitude_meters = be_read16(&rec->elevation) / 100.0; vdata = (char *) pdb_rec->data + sizeof(*rec); diff --git a/gpsbabel/holux.c b/gpsbabel/holux.c index 2bcff3c79..a233f9ba2 100644 --- a/gpsbabel/holux.c +++ b/gpsbabel/holux.c @@ -102,14 +102,14 @@ static void data_read(void) } iWptLen = sizeof(WPT); - iWptNum = ((WPTHDR *)HxWpt)->num; + iWptNum = le_read16(&((WPTHDR *)HxWpt)->num); /* Get the waypoints */ for (iCount = 0; iCount < iWptNum ; iCount ++) { wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); - iWptIndex = ((WPTHDR *)HxWpt)->idx[iCount]; /* get the waypoint index */ + iWptIndex = le_read16(&((WPTHDR *)HxWpt)->idx[iCount]); dwIndex= OFFS_WPT + (sizeof(WPT) * iWptIndex); pWptHxTmp = (WPT *)&HxWpt[OFFS_WPT + (sizeof(WPT) * iWptIndex)]; @@ -137,8 +137,8 @@ static void data_read(void) wpt_tmp->creation_time = mktime(&tm); } - lon = (double)pWptHxTmp->pt.iLongitude / 36000; - lat = ((double)pWptHxTmp->pt.iLatitude / 36000) * -1; + lon = le_read32(&pWptHxTmp->pt.iLongitude) / 36000.0; + lat = (le_read32(&pWptHxTmp->pt.iLatitude) / 36000.0) * -1.0; wpt_tmp->position.longitude.degrees = lon; wpt_tmp->position.latitude.degrees = lat; waypt_add(wpt_tmp); @@ -187,8 +187,9 @@ static void holux_disp(const waypoint *wpt) lat += (double)((int)lat/abs((int)lat)) * .5; - sIndex = ((WPTHDR *)HxWFile)->num; + sIndex = le_read16(&((WPTHDR *)HxWFile)->num); ((WPTHDR *)HxWFile)->idx[sIndex] = sIndex; /* set the waypoint index */ + le_write16(&((WPTHDR *)HxWFile)->idx[sIndex], sIndex); /* set the waypoint index */ ((WPTHDR *)HxWFile)->used[sIndex] = 0xff; /* Waypoint used */ @@ -224,12 +225,12 @@ static void holux_disp(const waypoint *wpt) } - pWptHxTmp->pt.iLatitude = (int)lat; - pWptHxTmp->pt.iLongitude = (int)lon; + le_write32(&pWptHxTmp->pt.iLatitude,(unsigned int) lat); + le_write32(&pWptHxTmp->pt.iLongitude,(unsigned int) lon); pWptHxTmp->checked = 01; pWptHxTmp->vocidx = (short)0xffff; - ((WPTHDR *)HxWFile)->num = ++sIndex; - ((WPTHDR *)HxWFile)->next= ++sIndex; + le_write16(&((WPTHDR *)HxWFile)->num, ++sIndex); + le_write16(&((WPTHDR *)HxWFile)->next, ++sIndex); } @@ -244,7 +245,7 @@ static void data_write(void) short sCount; /* init the waypoint area*/ - ((WPTHDR *)HxWFile)->id = WPT_HDR_ID; + le_write32(&((WPTHDR *)HxWFile)->id, WPT_HDR_ID); ((WPTHDR *)HxWFile)->num = 0; ((WPTHDR *)HxWFile)->next = 0; @@ -253,12 +254,11 @@ static void data_write(void) ((WPTHDR *)HxWFile)->idx[sCount] = (signed short)-1; for (sCount = 0; sCount < MAXWPT; sCount++) ((WPTHDR *)HxWFile)->used[sCount] = 0; - /* init the route area */ - ((RTEHDR *)&HxWFile[ROUTESTART])->id = RTE_HDR_ID; + le_write32(&((RTEHDR *)&HxWFile[ROUTESTART])->id, RTE_HDR_ID); ((RTEHDR *)&HxWFile[ROUTESTART])->num = 0; - ((RTEHDR *)&HxWFile[ROUTESTART])->next = 1; + le_write16(&((RTEHDR *)&HxWFile[ROUTESTART])->next, 1); ((RTEHDR *)&HxWFile[ROUTESTART])->rteno = (signed short)-1; /* clear index list */ @@ -267,7 +267,6 @@ static void data_write(void) for (sCount = 0; sCount < MAXRTE; sCount++) ((RTEHDR *)&HxWFile[ROUTESTART])->used[sCount] = 0; - waypt_disp_all(holux_disp); diff --git a/gpsbabel/magnav.c b/gpsbabel/magnav.c index 699b27f76..93cd69c70 100644 --- a/gpsbabel/magnav.c +++ b/gpsbabel/magnav.c @@ -107,10 +107,10 @@ data_read(void) wpt_tmp = xcalloc(sizeof(*wpt_tmp),1); rec = (struct record *) pdb_rec->data; - wpt_tmp->position.altitude.altitude_meters = pdb_read4(&rec->elevation); + wpt_tmp->position.altitude.altitude_meters = be_read32(&rec->elevation); - wpt_tmp->position.longitude.degrees = pdb_read4(&rec->longitude) / 1e5; - wpt_tmp->position.latitude.degrees = pdb_read4(&rec->latitude) / 1e5; + wpt_tmp->position.longitude.degrees = be_read32(&rec->longitude) / 1e5; + wpt_tmp->position.latitude.degrees = be_read32(&rec->latitude) / 1e5; vdata = (char *) pdb_rec->data + sizeof(*rec); @@ -120,12 +120,12 @@ data_read(void) wpt_tmp->description = xstrdup(vdata); vdata += strlen (vdata) + 1; - tm.tm_sec = pdb_read2(&rec->crt_sec); - tm.tm_min = pdb_read2(&rec->crt_min); - tm.tm_hour = pdb_read2(&rec->crt_hour); - tm.tm_mday = pdb_read2(&rec->crt_mday); - tm.tm_mon = pdb_read2(&rec->crt_mon) - 1; - tm.tm_year = pdb_read2(&rec->crt_year) - 1900; + tm.tm_sec = be_read16(&rec->crt_sec); + tm.tm_min = be_read16(&rec->crt_min); + tm.tm_hour = be_read16(&rec->crt_hour); + tm.tm_mday = be_read16(&rec->crt_mday); + tm.tm_mon = be_read16(&rec->crt_mon) - 1; + tm.tm_year = be_read16(&rec->crt_year) - 1900; wpt_tmp->creation_time = mktime(&tm); waypt_add(wpt_tmp); @@ -166,9 +166,9 @@ abort(); rec->year = 0xff; } - pdb_write4(&rec->longitude, wpt->position.longitude.degrees * 10000000.0); - pdb_write4(&rec->latitude, wpt->position.latitude.degrees * 10000000.0); - pdb_write4(&rec->elevation, wpt->position.altitude.altitude_meters * 100.0); + be_write32(&rec->longitude, wpt->position.longitude.degrees * 10000000.0); + be_write32(&rec->latitude, wpt->position.latitude.degrees * 10000000.0); + be_write32(&rec->elevation, wpt->position.altitude.altitude_meters * 100.0); opdb_rec = new_Record (0, 0, ct++, sizeof(*rec), (const ubyte *)rec); diff --git a/gpsbabel/psp.c b/gpsbabel/psp.c index 73c5bce78..85b6a4898 100644 --- a/gpsbabel/psp.c +++ b/gpsbabel/psp.c @@ -36,8 +36,27 @@ static FILE *psp_file_in; static FILE *psp_file_out; +static int i_am_little_endian; +static int endianness_tested; + +static void +test_endianness(void) +{ + union { + long l; + unsigned char uc[sizeof (long)]; + } u; + + u.l = 1; + i_am_little_endian = u.uc[0]; + + endianness_tested = 1; + +} + static int -psp_fread(void *buff, size_t size, size_t members, FILE * fp) { +psp_fread(void *buff, size_t size, size_t members, FILE * fp) +{ size_t br; br = fread(buff, size, members, fp); @@ -49,8 +68,76 @@ psp_fread(void *buff, size_t size, size_t members, FILE * fp) { return (br); } +static double +psp_fread_double(FILE *fp) +{ + unsigned char buf[8]; + unsigned char sbuf[8]; + psp_fread(buf, 1, 8, psp_file_in); + if (i_am_little_endian) { + return *(double *) buf; + } + sbuf[0] = buf[7]; + sbuf[1] = buf[6]; + sbuf[2] = buf[5]; + sbuf[3] = buf[4]; + sbuf[4] = buf[3]; + sbuf[5] = buf[2]; + sbuf[6] = buf[1]; + sbuf[7] = buf[0]; + return *(double *)sbuf; +} + +static void +psp_fwrite_double(double x, FILE *fp) +{ + unsigned char *cptr = (unsigned char *)&x; + unsigned char cbuf[8]; + + if (!endianness_tested) { + test_endianness(); + } + if (i_am_little_endian) { + fwrite(&x, 8, 1, fp); + } else { + cbuf[0] = cptr[7]; + cbuf[1] = cptr[6]; + cbuf[2] = cptr[5]; + cbuf[3] = cptr[4]; + cbuf[4] = cptr[3]; + cbuf[5] = cptr[2]; + cbuf[6] = cptr[1]; + cbuf[7] = cptr[0]; + fwrite(cbuf, 8, 1, fp); + } + +} +#if 0 +static void +psp_fwrite_word(unsigned int x, FILE *fp) +{ + char *cptr = &x; + char *cbuf[4]; + + if (!endianness_tested) { + test_endianness(); + } + if (i_am_little_endian) { + fwrite(&x, 4, 1, fp); + } else { + cbuf[0] = cptr[3]; + cbuf[1] = cptr[2]; + cbuf[2] = cptr[1]; + cbuf[3] = cptr[0]; + fwrite(cbuf, 4, 1, fp); + } +} +#endif + + static int -valid_psp_header(char * header, int len) { +valid_psp_header(char * header, int len) +{ char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x00 }; /* 1niP */ char *p, *s; @@ -119,7 +206,7 @@ psp_wr_deinit(void) static void psp_read(void) { - char buff[MAXPSPSTRINGSIZE + 1]; + unsigned char buff[MAXPSPSTRINGSIZE + 1]; double radians; waypoint *wpt_tmp; int stringsize; @@ -132,7 +219,7 @@ psp_read(void) fatal(MYNAME ": input file does not appear to be a valid .PSP file.\n"); } - pincount = *(short int *)&buff[12]; + pincount = le_read16(&buff[12]); while (pincount--) { wpt_tmp = xcalloc(sizeof(*wpt_tmp),1); @@ -158,13 +245,11 @@ psp_read(void) psp_fread(&buff[0], 1, 1, psp_file_in); /* 8 bytes - latitude in radians */ - psp_fread(&buff[0], 1, 8, psp_file_in); - radians = *(double *)&buff[0]; + radians = psp_fread_double(psp_file_in); wpt_tmp->position.latitude.degrees = (radians * 180.0) / M_PI; /* 8 bytes - longitude in radians */ - psp_fread(&buff[0], 1, 8, psp_file_in); - radians = *(double *)&buff[0]; + radians = psp_fread_double(psp_file_in); wpt_tmp->position.longitude.degrees = (radians * 180.0) / M_PI; /* 1 byte - pin display properties */ @@ -236,7 +321,7 @@ static void psp_waypt_pr(const waypoint *wpt) { double lon, lat; - char tbuf[64]; + unsigned char tbuf[64]; char c; int i; char *shortname; @@ -278,10 +363,10 @@ psp_waypt_pr(const waypoint *wpt) fwrite(&c, 1, 1, psp_file_out); /* 8 bytes - latitude/radians */ - fwrite(&lat, 1, 8, psp_file_out); + psp_fwrite_double(lat, psp_file_out); /* 8 bytes - longitude/radians */ - fwrite(&lon, 1, 8, psp_file_out); + psp_fwrite_double(lon, psp_file_out); /* 1 byte - pin properties */ c = 0x14; /* display pin name on! display notes on! */ @@ -347,7 +432,7 @@ psp_write(void) } /* insert waypoint count into header */ - memcpy(&header_bytes[12], &s, 2); + le_write16(&header_bytes[12], s); fwrite(&header_bytes, 1, 32, psp_file_out); diff --git a/gpsbabel/util.c b/gpsbabel/util.c index 08401650b..999f899c0 100644 --- a/gpsbabel/util.c +++ b/gpsbabel/util.c @@ -104,21 +104,21 @@ fatal(const char *fmt, ...) * Read 4 bytes in big-endian. Return as "int" in native endianness. */ signed int -pdb_read4(pdb_32 *p) +be_read32(void *p) { unsigned char *i = (unsigned char *) p; return i[0] << 24 | i[1] << 16 | i[2] << 8 | i[3]; } signed int -pdb_read2(pdb_16 *p) +be_read16(void *p) { char *i = (char *) p; return i[0] << 8 | i[0]; } void -pdb_write4(pdb_32 *pp, unsigned i) +be_write32(void *pp, unsigned i) { char *p = (char *)pp; @@ -127,3 +127,37 @@ pdb_write4(pdb_32 *pp, unsigned i) p[2] = (i >> 8) & 0xff; p[3] = i & 0xff; } + +signed int +le_read16(void *addr) +{ + unsigned char *p = addr; + return p[0] | (p[1] << 8); +} + +signed int +le_read32(void *addr) +{ + unsigned char *p = addr; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +void +le_write16(void *addr, unsigned value) +{ + unsigned char *p = addr; + p[0] = value; + p[1] = value >> 8; + +} + +void +le_write32(void *addr, unsigned value) +{ + unsigned char *p = addr; + p[0] = value; + p[1] = value >> 8; + p[2] = value >> 16; + p[3] = value >> 24; +} + -- 2.30.2